﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace THenu.TinyHourseLib.EventAndDelegate.Weak_Reference
{
    public class DisposableCache
    {
        static Dictionary<int, WeakReference> _CacheManager = new Dictionary<int, WeakReference>();

        int regenCount = 0;

        public DisposableCache(int count)
        {
            _CacheManager.Clear();
            for (int i = 0; i < count; i++)
            {
                _CacheManager.Add(i, new WeakReference(new Data(i), false));
            }
        }
        // Number of items in the cache.
        public int Count
        {
            get { return _CacheManager.Count; }
        }

        // Number of times an object needs to be regenerated.
        public int RegenerationCount
        {
            get { return regenCount; }
        }
        // Retrieve a data object from the cache.
        public Data this[int index]
        {
            get
            {
                Data d = _CacheManager[index].Target as Data;
                if (d == null)
                {
                    // If the object was reclaimed, generate a new one.
                    Console.WriteLine("Regenerate object at {0}: Yes", index);
                    d = new Data(index);
                    _CacheManager[index].Target = d;
                    regenCount++;
                }
                else
                {
                    // Object was obtained with the weak reference.
                    Console.WriteLine("Regenerate object at {0}: No", index);
                }

                return d;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public static void DiaplayMain()
        {
            // Create the cache.
            int cacheSize = 50;
            Random r = new Random();
            DisposableCache dc = new DisposableCache(cacheSize);

            string DataName = "";
            //GC.Collect(0);

            // Randomly access objects in the cache.
            for (int i = 0; i < dc.Count; i++)
            {
                int index = r.Next(dc.Count);

                // Access the object by getting a property value.
                DataName = dc[index].Name;
            }
            // Show results.
            double regenPercent = dc.RegenerationCount / (double)dc.Count;
            Console.WriteLine("Cache size: {0}, Regenerated: {1:P2}%", dc.Count, regenPercent);
        }
    }
    // This class creates byte arrays to simulate data.
    public class Data
    {
        private byte[] _data;
        private string _name;

        public Data(int size)
        {
            _data = new byte[size * 1024];
            _name = size.ToString();
        }

        // Simple property.
        public string Name
        {
            get { return _name; }
        }
    }
}
